﻿/*
 * @author: wizardc
 */

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

namespace DouEditor.Extend
{
    /// <summary>
    /// 自定义快捷键管理器
    /// 内部基于 Unity 自身提供的 UnityEditor.ShortcutManagement.ShortcutManager 实现，因为自带的窗口项目非常多，这里对自定义的快捷键提供一个精简的窗口和方便使用的接口。
    /// <example>
    /// public class CustomEditor : EditorWindow
    /// {
    ///     // InitializeOnLoadMethod 标签确保编辑器加载后就注册自定义快捷键配置
    ///     [InitializeOnLoadMethod]
    ///     static void Initialize()
    ///     {
    ///         ShortcutMgr.instance.RegisterShortcut("Config Export", "配置表", "导表", "立即导出配置表", KeyCode.Keypad5); // 注册快捷键，可以同时设定快捷键的默认值
    ///     }
    ///     // 必须配合 Shortcut 标签来确定按下快捷键后执行的方法（注 MenuItem 标签也可以支持快捷键）
    ///     [Shortcut("Config Export")]
    ///     public static void ExportConfig()
    ///     {
    ///         // 这里编写响应快捷键的代码
    ///     }
    /// }
    /// </example>
    /// </summary>
    public class ShortcutSettingsWindow : EditorWindow
    {
        [MenuItem("DouFramework/快捷键配置")]
        public static void ShowWindow()
        {
            GetWindow<ShortcutSettingsWindow>("快捷键配置");
        }
        
        private Dictionary<string, bool> _categoryFoldouts = new Dictionary<string, bool>();
        
        private Vector2 _scrollPosition;
        private string _searchText = "";
        
        private bool _isRecording = false;
        private ShortcutConfig _editingShortcut;

        void OnEnable()
        {
            ApplyAllShortcuts();
            
            foreach (var shortcut in ShortcutMgr.instance._shortcutData.shortcuts)
            {
                if (!_categoryFoldouts.ContainsKey(shortcut.category))
                {
                    _categoryFoldouts[shortcut.category] = true;
                }
            }
        }

        void OnGUI()
        {
            DrawHeader();
            DrawSearchBar();
            DrawShortcutList();
            DrawFooter();
        }

        private void DrawHeader()
        {
            GUILayout.Space(10);

            EditorGUILayout.BeginHorizontal();
            GUILayout.FlexibleSpace();

            GUILayout.Label("自定义快捷键配置", EditorStyles.boldLabel);

            GUILayout.FlexibleSpace();
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(10);

            EditorGUILayout.HelpBox("点击快捷键字段开始录制，按下新的组合键后自动保存。", MessageType.Info);

            GUILayout.Space(10);
        }

        private void DrawSearchBar()
        {
            EditorGUILayout.BeginHorizontal();

            GUILayout.Label("搜索:", GUILayout.Width(40));
            _searchText = EditorGUILayout.TextField(_searchText);

            if (GUILayout.Button("清空", GUILayout.Width(50)))
            {
                _searchText = "";
            }

            EditorGUILayout.EndHorizontal();

            GUILayout.Space(10);
        }

        private void DrawShortcutList()
        {
            _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);

            Dictionary<string, List<ShortcutConfig>> categorized = new Dictionary<string, List<ShortcutConfig>>();

            foreach (var shortcut in ShortcutMgr.instance._shortcutData.shortcuts)
            {
                if (!string.IsNullOrEmpty(_searchText) &&
                    !shortcut.name.ToLower().Contains(_searchText.ToLower()) &&
                    !shortcut.desc.ToLower().Contains(_searchText.ToLower()) &&
                    !shortcut.category.ToLower().Contains(_searchText.ToLower()))
                {
                    continue;
                }

                if (!categorized.ContainsKey(shortcut.category))
                {
                    categorized[shortcut.category] = new List<ShortcutConfig>();
                }

                categorized[shortcut.category].Add(shortcut);
            }

            foreach (var category in categorized)
            {
                _categoryFoldouts[category.Key] = EditorGUILayout.Foldout(_categoryFoldouts.ContainsKey(category.Key) ? _categoryFoldouts[category.Key] : true, $"{category.Key} ({category.Value.Count})", true);
                
                if (_categoryFoldouts[category.Key])
                {
                    EditorGUI.indentLevel++;

                    foreach (var shortcut in category.Value)
                    {
                        DrawShortcutItem(shortcut);
                    }

                    EditorGUI.indentLevel--;
                }

                GUILayout.Space(5);
            }

            EditorGUILayout.EndScrollView();
        }

        private void DrawShortcutItem(ShortcutConfig shortcut)
        {
            EditorGUILayout.BeginVertical("box");

            EditorGUILayout.BeginHorizontal();

            EditorGUILayout.BeginVertical();
            GUILayout.Label(shortcut.name, EditorStyles.boldLabel);
            GUILayout.Label(shortcut.desc, EditorStyles.miniLabel);
            EditorGUILayout.EndVertical();

            GUILayout.FlexibleSpace();

            DrawShortcutField(shortcut);

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();
        }

        private void DrawShortcutField(ShortcutConfig shortcut)
        {
            bool isEditing = (_editingShortcut == shortcut);

            string buttonText = isEditing ? "录制中..." : shortcut.GetKeyString();
            GUIStyle buttonStyle = isEditing ? new GUIStyle(GUI.skin.button) { normal = { textColor = Color.red } } : GUI.skin.button;

            if (GUILayout.Button(buttonText, buttonStyle, GUILayout.Width(120)))
            {
                if (isEditing)
                {
                    StopRecording();
                }
                else
                {
                    StartRecording(shortcut);
                }
            }

            if (GUILayout.Button("应用", GUILayout.Width(40)))
            {
                ShortcutMgr.instance.ApplyShortcut(shortcut);
            }

            if (GUILayout.Button("置空", GUILayout.Width(40)))
            {
                ResetToDefault(shortcut);
            }

            if (isEditing && Event.current.isKey && Event.current.type == EventType.KeyDown)
            {
                ProcessKeyRecording(shortcut, Event.current);
            }
        }

        private void StartRecording(ShortcutConfig shortcut)
        {
            if (_isRecording && _editingShortcut != null)
            {
                StopRecording();
            }

            _editingShortcut = shortcut;
            _isRecording = true;
            Repaint();
        }

        private void StopRecording()
        {
            _editingShortcut = null;
            _isRecording = false;
            Repaint();
        }

        private void ProcessKeyRecording(ShortcutConfig shortcut, Event currentEvent)
        {
            // 忽略功能键和鼠标键
            if (currentEvent.keyCode == KeyCode.None
                || currentEvent.keyCode == KeyCode.LeftControl || currentEvent.keyCode == KeyCode.RightControl
                || currentEvent.keyCode == KeyCode.LeftShift || currentEvent.keyCode == KeyCode.RightShift
                || currentEvent.keyCode == KeyCode.LeftAlt || currentEvent.keyCode == KeyCode.RightAlt
                || (currentEvent.keyCode >= KeyCode.Mouse0 && currentEvent.keyCode <= KeyCode.Mouse6))
            {
                return;
            }

            // 检查是否按下了 Escape 取消
            if (currentEvent.keyCode == KeyCode.Escape)
            {
                StopRecording();
                return;
            }

            shortcut.keyCode = currentEvent.keyCode;
            shortcut.control = currentEvent.control;
            shortcut.shift = currentEvent.shift;
            shortcut.alt = currentEvent.alt;

            ShortcutMgr.instance.SaveShortcuts();
            StopRecording();

            ShortcutMgr.instance.ApplyShortcut(shortcut);
            
            // 使用事件，防止传播
            currentEvent.Use();
        }
        
        private void ResetToDefault(ShortcutConfig shortcut)
        {
            shortcut.keyCode = KeyCode.None;
            shortcut.control = false;
            shortcut.shift = false;
            shortcut.alt = false;

            ShortcutMgr.instance.ApplyShortcut(shortcut);
            ShortcutMgr.instance.SaveShortcuts();
            Repaint();
        }

        private void DrawFooter()
        {
            GUILayout.Space(10);

            EditorGUILayout.BeginHorizontal();

            if (GUILayout.Button("保存配置"))
            {
                ShortcutMgr.instance.SaveShortcuts();
                EditorUtility.DisplayDialog("成功", "快捷键配置已保存", "确定");
            }

            if (GUILayout.Button("应用所有"))
            {
                if (EditorUtility.DisplayDialog("确认", "确定要应用所有快捷键吗？", "是", "否"))
                {
                    ApplyAllShortcuts();
                }
            }

            if (GUILayout.Button("置空所有"))
            {
                if (EditorUtility.DisplayDialog("确认", "确定要置空所有快捷键吗？", "是", "否"))
                {
                    ResetAllShortcuts();
                }
            }

            EditorGUILayout.EndHorizontal();
        }

        private void ApplyAllShortcuts()
        {
            foreach (var shortcut in ShortcutMgr.instance._shortcutData.shortcuts)
            {
                ShortcutMgr.instance.ApplyShortcut(shortcut);
            }
        }

        private void ResetAllShortcuts()
        {
            foreach (var shortcut in ShortcutMgr.instance._shortcutData.shortcuts)
            {
                shortcut.keyCode = KeyCode.None;
                shortcut.control = false;
                shortcut.shift = false;
                shortcut.alt = false;
                ShortcutMgr.instance.ApplyShortcut(shortcut);
            }

            ShortcutMgr.instance.SaveShortcuts();
            Repaint();
        }
    }
}
